home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-06-08 | 42.5 KB | 1,252 lines |
- (* :Title: Forward Laplace Transform Package *)
-
- (* :Authors: Brian Evans, James McClellan *)
-
- (* :Summary: *)
-
- (* :Context: SignalProcessing`Analog`LaPlace` *)
-
- (* :PackageVersion: 2.6 *)
-
- (*
- :Copyright: Copyright 1990-1991 by Brian L. Evans
- Georgia Tech Research Corporation
-
- Permission to use, copy, modify, and distribute this software
- and its documentation for any purpose and without fee is
- hereby granted, provided that the above copyright notice
- appear in all copies and that both that copyright notice and
- this permission notice appear in supporting documentation,
- and that the name of the Georgia Tech Research Corporation,
- Georgia Tech, or Georgia Institute of Technology not be used
- in advertising or publicity pertaining to distribution of the
- software without specific, written prior permission. Georgia
- Tech makes no representations about the suitability of this
- software for any purpose. It is provided "as is" without
- express or implied warranty.
- *)
-
- (*
- :History: began -- February, 1990 (adapted from "ZTransform.m")
- added Dialogue ability -- February, 1991
- *)
-
- (* :Keywords: *)
-
- (*
- :Source: Muth, E. J. {Transform Methods}. 1977.
- Franklin, G. F. {Feedback Control of Dynamic Systems}. 1986.
- Bracewell. {The Fourier Transform and Its Applications}. 1978.
- Nilsson, J. W. {Electric Circuits}
- Churchill, R. {Operational Mathematics}. 1958.
- Oberhettinger, F., and Badii, L. {Tables of Laplace
- Transforms}, 1973.
- *)
-
- (*
- :Warning: Keep conditional clauses (code following /;) on the same line;
- breaking a clause into lines separated by RETURNS will
- confuse Mathematica (e.g., the active context for this
- package will not be reset to Global).
- *)
-
- (* :Mathematica Version: 1.2 or 2.0 *)
-
- (* :Limitation: *)
-
- (*
- :Discussion: All new functions have usage information.
- The 1-D rule base has a total of 102 rules:
-
- I. multidimensional hooks 3 rules
- II. rational transform pairs 13 rules
- III. non-rational transform pairs 40 rules
- IV. transform properties 23 rules *
- V. transforms of SP structures 14 rules **
- VI. transform strategies 9 rules
-
- * one rule has been commented out
- ** two rules have been commented out
-
- The only purpose to the multidimensional hook rules is to track
- the region of convergence for non-separable functions. Without
- these rules, the z-transform rule base would still properly
- compute the z-transform function. Otherwise, the CTFTransform
- would not work properly for functions like Exp[-(6/7)^t1]
- Exp[-(9/10)^t2] Delta[t1 - t2] CStep[t1, t2] with respect to
- variables t1 and t2.
-
- At each step in the Laplace rule base, the current expression
- has a local state associated with it. This state consists of
- a list of six boolean values. Each boolean value is associated
- with a strategy. If an element is True, then that strategy has
- not been tried yet; if False, then that strategy has already
- been tried, and it will not be tried again. Thus, local state
- is used to prevent infinite loops which would be caused by the
- repetitive application of certain strategy rules. See the
- section S T A T E D E F I N I T I O N below and section VI
- of the rules.
-
- MyLaPlace[ f[t], t, s, state, tlist, slist ] is one-dimensional
- Laplace transform rule base. It returns the transform of f[t]
- as a three-element list: { F(s), Rminus, Rplus }. The "time"
- variable being transform is t, and s is the Laplace variable.
- The complete collection of time variables is in tlist and
- Laplace variables in slist. Note that LaPlace drives the rule
- base defined by MyLaPlace when computing the forward LaPlace
- transform.
- *)
-
- (* :Functions: LaPlace *)
-
-
- If [ TrueQ[ $VersionNumber >= 2.0 ],
- Off[ General::spell ];
- Off[ General::spell1 ] ];
-
-
- (* B E G I N P A C K A G E *)
-
- BeginPackage[ "SignalProcessing`Analog`LaPlace`",
- "SignalProcessing`Analog`LSupport`",
- "SignalProcessing`Support`TransSupport`",
- "SignalProcessing`Support`ROC`",
- "SignalProcessing`Support`SigProc`",
- "SignalProcessing`Support`SupCode`",
- "SignalProcessing`Support`FilterSupport`" ]
-
-
- (* U S A G E I N F O R M A T I O N *)
-
- LaPlace::usage =
- "LaPlace[e, t] or LaPlace[e, t, s] gives the two-sided Laplace \
- transform of the expression e, which is a function of t, by \
- returning an object of four slots tagged by LTransData: \
- <transform>, <rminus>, <rplus>, <laplace_variables>. \
- The Region of Convergence (ROC) is defined as \
- <rminus> < Re{s} < <rplus>. \
- Note that the returned ROC is either the actual ROC or a subset \
- of the actual ROC. \
- In two dimensions, LaPlace[e, {t1, t2}, {s1, s2}] \
- is the same as LaPlace [ LaPlace[e, t1, s1], t2, s2 ]. \
- This notation extends naturally to higher dimensions. \
- Note that the right-sided transform is specified by \
- multiplying the expression by CStep[t]. \
- Also, LaPlaceTransform is an alias for LaPlace."
-
- (* E N D U S A G E I N F O R M A T I O N *)
-
-
- Begin["`Private`"]
-
-
- (* U S E R I N T E R F A C E *)
-
- (* L operator *)
- Unprotect[L]
- L/: TheFunction[ L[t_, s_][f_] ] := LaPlace[f, t, s]
- Protect[L]
-
- (* LaPlace *)
- LaPlace/: Options[ LaPlace ] :=
- { Definition -> False, Dialogue -> True,
- Simplify -> True, TransformLookup -> {} }
-
- LaPlace[e_] :=
- laplacedriver[ Options[LaPlace], e ]
- LaPlace[e_, t_] :=
- laplacedriver[ Options[LaPlace], e, t ]
- LaPlace[e_, t_, s_] :=
- laplacedriver[ Options[LaPlace], e, t, s ]
- LaPlace[e_, t_, s_, op__] :=
- laplacedriver[ ToList[op] ~Join~ Options[LaPlace], e, t, s ]
-
- (* Interface support for LaPlace *)
- laplacedriver[op_, f_, args__] :=
- cleanup [ laplace[op, ToContinuous[f], args],
- Replace[Dialogue, op],
- TrueQ[Replace[Simplify, op]] ]
-
- laplace[op_, f_, args___] :=
- Block [ {},
- Replace [ ltrans[op, f, args], LaPlaceInterfaceRules ] ]
-
- LaPlaceInterfaceRules = {
- ltrans[op_, e_] :>
- Message[Transform::novariables, "t (time)", GetVariables[e]],
-
- ltrans[op_, e_, t_] :> e /; LTransformQ[e],
- ltrans[op_, e_, t_] :>
- laplace[op, e, t, DummyVariables[Length[t], Global`s] ] /;
- validvarQ[t],
-
- ltrans[op_, e_, t_, rest___] :>
- Message[ Transform::badvar, "time", LaPlace, t ] /;
- ! validvarQ[t],
- ltrans[op_, e_, t_, s_, rest___] :>
- Message[ Transform::badvar, "s", LaPlace, s ] /;
- ! validvarQ[s],
-
- ltrans[op_, e_, t_List, sl_] :>
- MultiDTransform[ MakeLObject, laplace,
- LTransformQ, e, t, s, sl, op ],
-
- ltrans[op_, e_, t_Symbol, s_Symbol] :>
- laplace[op, e, t, s, {t}, {s}],
- ltrans[op_, e_, t_Symbol, s_Symbol, tlist_, slist_] :>
- If [ SameQ[ToList[LVariables[e]], slist],
- e,
- LMultiDROC[laplace[op, TheFunction[e], t, s, tlist, slist],
- e] ] /;
- LTransformQ[e],
- ltrans[op_, e_, t_Symbol, s_Symbol, tlist_, slist_] :>
- MakeLObject [ MyLaPlace [ e, t, s, initLstate[],
- tlist, slist, op ],
- s ] /;
- ! LTransformQ[e]
- }
-
- cleanup[ Null, dialogue_, simplify_ ] := Null
-
- cleanup[trans_, dialogue_, simplify_ ] :=
- Block [ {dialflag, retval},
- retval = trans;
- dialflag = SameQ[dialogue, All];
- If [ simplify,
- Off[Replace::rep];
- retval = SPSimplify[trans, Dialogue -> dialflag];
- On[Replace::rep] ];
- If [ dialogue || dialflag,
- Scan[explain, retval, Infinity] ];
- retval ]
-
- explain[ mylaplace[ f_, t_, rest__ ] ] :=
- Message[ Transform::incomplete, "forward Laplace transform", f, t ]
-
- validvarQ[ x_Symbol ] := True
- validvarQ[ x_List ] := Apply[And, Map[VariableQ, x]]
- validvarQ[ x_ ] := False
-
-
- (* S U P P O R T I N G R O U T I N E S F O R R U L E B A S E *)
-
- absDialogue[f_, t_, options_] :=
- Block [ {dialogue, result},
- dialogue = InformUserQ[ options ];
- result = (f /. Abs[a_. t] :> Abs[a] t) CStep[t] +
- (f /. Abs[b_. t] :> - Abs[b] t) CStep[-t];
-
- If [ dialogue,
- Print[ "( after rewriting the two-sided expression" ];
- Print[ " ", f ];
- Print[ " as a left-sided plus a right-sided function:"];
- Print[ " ", result, " . )" ] ];
-
- result ]
-
- addL[trans1_, trans2_] := AddT[LForm, trans1, trans2, -Infinity]
-
- antiCausalL[trans_, s_] :=
- Transform[ TheFunction[trans] /. s -> -s,
- -GetRPlus[trans], -GetRMinus[trans] ] /;
- LForm[trans]
-
- conjL[trans_, s_] := ConjT[LForm, trans, s]
-
- convolveL[convop_, trans1_, trans2_] :=
- ConvolveT[LForm, convop, trans1, trans2]
-
- definitionDialogue[ oldexpr_, trans_, operator_, options_ ] :=
- Block [ {},
- If [ InformUserQ[options],
- Print[ "( after using ", operator,
- " to apply the definition to" ];
- Print[ " ", oldexpr ];
- Print[ " to find its transform"];
- Print[ " ", trans, " )" ] ];
- trans ]
-
- integrateL[trans_, s_] := IntegrateT[LForm, trans, s, s, Infinity]
-
- lDerivative[trans_, s_, m_] := scaleL[DerivativeT[LForm, trans, s, m], (-1)^m]
-
- lineImpulseMDL[trans_, s_, slist_, sleft_] :=
- LineImpulsemDT[LForm, trans, s, slist, sleft, Plus]
-
- lMultiplyByExp[trans_, s_, a_] :=
- Block [ {newrm, newrp, transform},
- newrm = GetRMinus[trans] - Re[a];
- newrp = GetRPlus[trans] - Re[a];
- transform = Transform[ TheFunction[trans], newrm, newrp ];
- substituteForL[transform, s, s+a] ] /;
- LForm[trans]
-
- multL[trans1_, trans2_] := MultT[LForm, trans1, trans2, -Infinity]
-
- scaleL[trans_, c_] := ScaleT[LForm, trans, c]
-
- similarityL[x_, s_, scale_] :=
- Block [ {adjrm, adjrp, newx},
- adjrm = GetRMinus[x];
- If [ ! InfinityQ[adjrm], adjrm *= scale ];
- adjrp = GetRPlus[x];
- If [ ! InfinityQ[adjrp], adjrp *= scale ];
- newx = Transform[ TheFunction[x],
- Min[adjrm, adjrp],
- Max[adjrm, adjrp] ];
- scaleL[ substituteForL[ newx, s, s/scale ], 1/Abs[scale] ] ] /;
- LForm[x]
-
- similarityQ[f_, t_] :=
- Block [ {scale},
- scale = ScalingFactor[f, t];
- (! SameQ[scale, 1]) && (! SameQ[scale, 0]) ]
-
- subL[trans1_, trans2_] := SubT[LForm, trans1, trans2, -Infinity]
-
- substituteForL[trans_, s_, news_] := SubstituteForT[LForm, trans, s, news]
-
- summationL[trans_, op_ ] :=
- Block [ {fun, rm, rp},
- fun = TheFunction[trans];
- rm = GetRMinus[trans];
- rp = GetRPlus[trans];
- Transform[ op[fun], rm, rp ] ] /;
- LForm[trans]
-
- (* one-sided function *)
- timeDerivative[x_, s_, m_, f_, t_] :=
- Block [ {curderivative, i, result, rm, rp, xfun},
- rm = Max[0, GetRMinus[x]];
- rp = GetRPlus[x];
- xfun = TheFunction[x];
-
- result = s^m xfun - s^(m-1) Limit[f, t -> 0];
- curderivative = f;
- For [ i = 2, i <= m, i++,
- curderivative = D[curderivative, t];
- result -= s^(m-i) Limit[curderivative, t -> 0] ];
- Transform[result, rm, rp] ] /;
- LForm[x] && IntegerQ[m]
-
-
- (* S T A T E D E F I N T I O N *)
-
- (* In order of appearance in rule base *)
-
- polyfactorfield = 1 (* factor denominator if denom. is rat. poly *)
- partialfractionsfield = 2 (* partial fractions if denom. is rat. poly. *)
- expandfield = 3 (* apply Expand[] to expression *)
- expandallfield = 4 (* apply ExpandAll[] to expression *)
- collectallfield = 5 (* apply Collect to every level of expression *)
- stepfield = 6 (* multiply by (CStep[t] + CStep[-t]) *)
- thefunfield = 7 (* apply TheFunction[] to expression *)
- definitionfield = 8 (* apply definition of Laplace transform *)
-
- statevariables = 8
-
- initLstate[] := Table[True, {statevariables}]
- nullLstate[] := Table[False, {statevariables}]
-
-
- (* Driver for one-dimensional rule base *)
- (* First, convert all z /(z - a) forms to 1/(1 - a z^-1) *)
- (* since the rule base favors terms with z^-1 terms *)
- (* Loop until the expression to be inverted does not change. *)
- (* Use fixUp to remove the TransformLookup option before *)
- (* the options are passed on to the rule base; otherwise, *)
- (* the rule base could loop indefinitely. *)
- MyLaPlace[ f_, t_, s_, st_, tlist_, slist_, op_ ] :=
- Block [ {laste = Null, newe, newf, newlrules, trace},
-
- (* generate the forward Laplace transform rules *)
- newlrules = TransformFixUp[ t, s, op, mylaplace, True,
- LaPlace, -Infinity, Infinity ];
- LaPlaceRules = Join[ newlrules, OriginalLaPlaceRules ];
-
- (* determine the level of dialogue *)
- trace = SameQ[ Replace[Dialogue, op], All ];
-
- (* separate Sqrt[b t] forms into Sqrt[b] Sqrt[t] forms *)
- newf = f /. ( Sqrt[b_ t] :> Sqrt[b] Sqrt[t] /; FreeQ[b, t] );
-
- (* take the 1-D Laplace transform *)
- newe = mylaplace[newf, t, s, st, tlist, slist, fixUp[op]];
- While [ ! SameQ[ laste, newe ],
- If [ trace, Print[ newe ]; Print[ "which becomes" ] ];
- laste = newe;
- newe = MapAll[transform, laste] ];
- If [ trace, Print[ newe ] ];
-
- newe ]
-
- (* fixUp -- remove redundant options and the option TransformLookup *)
- fixUp[ op_ ] := { Definition -> Replace[Definition, op],
- Dialogue -> Replace[Dialogue, op],
- Simplify -> Replace[Simplify, op] }
-
- transform[ expr_ ] :=
- If [ SameQ[Head[expr], mylaplace],
- Replace [ expr, LaPlaceRules ],
- expr ]
-
-
- (* Format intermediate forms so that output from Dialogue -> All is readable *)
-
- Format[ mylaplace[ x_, t_, s_, st_, tlist_, slist_, op_ ] ] :=
- SequenceForm[ ColumnForm[{"L",
- " " ~StringJoin~ ToString[t]}],
- { x } ]
-
- Format[ antiCausalL[trans_, s_] ] :=
- SequenceForm[ {trans}, Subscript[s -> -s], Subscript[" and flip ROC "] ]
-
- Format[ lMultiplyByExp[trans_, s_, a_] ] :=
- SequenceForm[ {trans},
- Subscript[s -> s + a],
- Subscript[" and shift ROC "] ]
-
- Format[ similarityL[trans_, s_, scale_] ] :=
- SequenceForm[ {trans},
- Subscript[s -> s/scale],
- Subscript[" and scale transform & ROC "] ]
-
- tdfmt = "`` - Summation[i, 0, ``, 1][`` Limit[ D[``, {``, i}], `` -> 0 ] ]"
-
- Format[ timeDerivative[x_, s_, m_, f_, t_] ] :=
- ToString[ StringForm[ tdfmt, s^m x, m - 1, s^(m - "i"), f, t, t ] ]
-
-
- (* B E G I N R U L E B A S E *)
-
-
- LaPlaceRules = {}
-
-
- OriginalLaPlaceRules = {
-
-
- (* I. M U L T I D I M E N S I O N A L H O O K S *)
-
-
- (* A. Region of convergence specification for dimension given *)
- (* by the variable n. Allows multi-dimensional LaPlace *)
- (* transforms like a^t1 Delta[t1 - t2] CStep[t1,t2] to be *)
- (* taken -- see Line impulses *)
- mylaplace[ SignalProcessing`ROCinfo[t_, rm_:-Infinity , rp_:Infinity], t_, s_,
- st_, tlist_, slist_, options_ ] :>
- Transform[ 1, rm, rp ],
-
-
- (* B. Multidimensional line Deltas become LineImpulses. *)
- mylaplace[ f_. Delta[k_. t1_Symbol + l_. t2_Symbol], t_, s_,
- st_, tlist_, slist_, options_ ] :>
- mylaplace[ f LineImpulse[{t1,t2}, {k,-l}], t, s,
- st, tlist, slist, options ] /;
- SubsetQ[{t1, t2}, tlist] && MemberQ[{t1, t2}, t],
-
-
- (* C. Line impulses. *)
- mylaplace[ f_. LineImpulse[varlist_, coefflist_], t_, s_,
- st_, tlist_, slist_, options_ ] :>
- Block [ {functionoft, slistmD},
- functionoft = f /. ReplaceWith[varlist, t / coefflist];
- slistmD = AssociateItem[varlist, tlist, slist];
- lineImpulseMDL [ mylaplace [ functionoft, t, s,
- st, tlist, slist, options ],
- s, slistmD, Complement[varlist,{t}]] ] /;
- FreeQ[f, LineImpulse[a__]],
-
-
-
-
- (* II. R A T I O N A L L A P L A C E T R A N S F O R M S *)
-
-
- (* A. Lookup rules for the zero, step, and impulse functions. *)
- mylaplace[ 0, t_, s_, st_, tlist_, slist_, options_ ] :>
- Transform[ 0, -Infinity, Infinity ],
-
- mylaplace[ CStep[t_], t_, s_, st_, tlist_, slist_, options_ ] :>
- Transform[ 1/s, 0, Infinity ],
-
- mylaplace[ f_. Delta[a_. t_ + t0_.], t_, s_, st_, tlist_, slist_, options_ ] :>
- Transform[ (f /. t -> -t0/a) Exp[s t0/a] / Abs[a],
- -Infinity, Infinity ] /;
- FreeQ[{a,t0}, t],
-
- mylaplace[ Unit[n_][t_ + t0_.], t_, s_, st_, tlist_, slist_, options_ ] :>
- Transform[ s^n Exp[s t0], -Infinity, Infinity ] /;
- IntegerQ[n] && n > 0 && FreeQ[t0, t],
-
- mylaplace[ t_^n_. CStep[t_], t_, s_, st_, tlist_, slist_, options_ ] :>
- Block [ {dialogue},
- dialogue = SameQ[Replace[Dialogue, options], All];
- Assuming[ n > 0, dialogue ];
- If [ dialogue && ! IntegerQ[n],
- Print[ "and that ", n, " is an integer" ] ];
- Transform[ n! / s^(n+1), 0, Infinity ] ] /;
- Implies[ NumberQ[n], IntegerQ[n] && n > 0 ],
-
-
- (* B. Sinusoidal functions -- note that cross terms like *)
- (* cos(at) cos(bt) are handled by properties *)
- mylaplace[ Sin[b_. + w_. t_] CStep[t_], t_, s_,
- st_, tlist_, slist_, options_ ] :>
- Transform[ (s Sin[b] + w Cos[b]) / (s^2 + w^2), 0, Infinity ] /;
- FreeQ[{b,w}, t], (* Modified from [Franklin, 591] *)
-
- mylaplace[ Cos[b_. + w_. t_] CStep[t_], t_, s_,
- st_, tlist_, slist_, options_ ] :>
- Transform[ (s Cos[b] - w Sin[b]) / (s^2 + w^2), 0, Infinity ] /;
- FreeQ[{b,w}, t], (* Modified from [Franklin, 591] *)
-
- mylaplace[ a_. Sinh[b_. + w_. t_] CStep[t_], t_, s_,
- st_, tlist_, slist_, options_ ] :>
- Transform[a (s Sinh[b] + w Cosh[b]) / (s^2 - w^2), Abs[w], Infinity] /;
- FreeQ[{a,b,w}, t], (* Modified from [Franklin, 591] *)
-
- mylaplace[ a_. Cosh[b_. + w_. t_] CStep[t_], t_, s_,
- st_, tlist_, slist_, options_ ] :>
- Transform[a (s Cosh[b] - w Sinh[b]) / (s^2 - w^2), Abs[w], Infinity] /;
- FreeQ[{a,b,w}, t], (* Modified from [Franklin, 591] *)
-
- mylaplace[ Sin[a_. t_]^2 CStep[t_], t_, s_,
- st_, tlist_, slist_, options_ ] :>
- Transform[ 2 a^2 / ( s (s^2 + 4 a^2) ), 2 Abs[Im[a]], Infinity ] /;
- FreeQ[a, t], (* [O & B, Formula 7.38] *)
-
- mylaplace[ Cos[a_. t_]^2 CStep[t_], t_, s_, st_, tlist_, slist_, options_ ] :>
- Transform[ (s^2 + 2 a^2)/(s (s^2 + 4 a^2)), 2 Abs[Im[a]], Infinity ] /;
- FreeQ[a, t], (* [O & B, Formula 7.39] *)
-
- (* C. Constant function *)
- mylaplace[ a_, t_, s_, st_, tlist_, slist_, options_ ] :>
- Transform[ a Delta[s], 0, 0 ] /;
- FreeQ[a, t],
-
- (* D. LaGuerre polynomials *)
- mylaplace[ LaguerreL[n_, t_ + b_.] CStep[t_], t_, s_,
- st_, tlist_, slist_, options_ ] :>
- Transform[ Exp[b s] ((s - 1)/s)^n / s, 0, Infinity ] /;
- FreeQ[{b,n}, t],
-
- (* E. Other rational transform pairs *)
- mylaplace[ t_^j_. BesselJ[j_, a_. t_] CStep[t_], t_, s_,
- st_, tlist_, slist_, options_ ] :>
- Transform[ (2 a)^j Gamma[j + 1/2] / ( Sqrt[Pi] (s^2 + a^2)^(j + 1/2) ),
- 0, Infinity ] /;
- FreeQ[{a,j}, t],
-
-
-
-
- (* III. N O N - R A T I O N A L L A P L A C E T R A N S F O R M S *)
-
-
- (* A. "Time" functions whose denominators are rational polys *)
-
- (* 1. Put functions with rational polynomial denominators *)
- (* in standard form (factor denominator, expand numer.) *)
- mylaplace[ p_, t_, s_, st_, tlist_, slist_, options_ ] :>
- mylaplace [ Expand[Numerator[p]] / ( Factor[Denominator[p]] ), t, s,
- SetStateField[st, polyfactorfield, False],
- tlist, slist, options ] /;
- GetStateField[st, polyfactorfield] &&
- PolynomialQ[Denominator[p], t] && RationalFunctionQ[p, t],
-
- (* 2. Normalize the factors of the denominator *)
- (* a. for numeric k, numeric j *)
- mylaplace[ ((a_ + b_ t_^j_.)^k_) x_., t_, s_,
- st_, tlist_, slist_, options_ ] :>
- b^k mylaplace[ x ( a/b + t^j )^k, t, s, st, tlist, slist, options ] /;
- FreeQ[{a,b},t] && IntegerQ[k] && (k < 0) && IntegerQ[j] && (j > 0),
-
- (* b. for symbolic k, numeric j *)
- mylaplace[ x_. / ((a_ + b_ t_^j_.)^k_.), t_, s_,
- st_, tlist_, slist_, options_ ] :>
- b^(- k) mylaplace[x / (a/b + t^j)^k, t, s, st, tlist, slist, options] /;
- FreeQ[{a,b,k},t] && IntegerQ[j] && (j > 0),
-
- (* 3. Partial fractions decomposition *)
- mylaplace[ p_, t_, s_, st_, tlist_, slist_, options_ ] :>
- mylaplace [ Apart[p, t], t, s,
- SetStateField[st, partialfractionsfield, False],
- tlist, slist, options ] /;
- GetStateField[st, partialfractionsfield] &&
- PolynomialQ[Denominator[p], t] && RationalFunctionQ[p, t],
-
- (* 4. Denominator sections *)
- mylaplace[ CStep[t_] / ( t_ + a_ ), t_, s_, st_, tlist_, slist_, options_ ] :>
- Transform[ - Exp[a s] ExpIntegralEi[- a s], 0, Infinity ] /;
- FreeQ[a, t], (* [O & B, Formula 2.9] *)
-
- mylaplace[ CStep[t_] / ( t_ + a_ )^2, t_, s_,
- st_, tlist_, slist_, options_ ] :>
- Transform[ 1 / a + s Exp[a s] ExpIntegralEi[- a s], 0, Infinity ] /;
- FreeQ[a, t],
-
- mylaplace[ CStep[t_] / ( t_^2 + b_ ), t_, s_,
- st_, tlist_, slist_, options_ ] :>
- Block [ {a, trans},
- a = Sqrt[b];
- trans = CosIntegral[a s] Sin[a s] / a -
- SinIntegral[a s] Cos[a s] / a;
- Transform[trans, 0, Infinity] ] /;
- FreeQ[b, t] && Positive[b], (* [O & B, Formula 2.16] *)
-
- mylaplace[ CStep[t_] / ( t_^2 + b_ ), t_, s_,
- st_, tlist_, slist_, options_ ] :>
- Block [ {g, trans},
- a = Sqrt[- b];
- trans = ExpIntegralEi[- a s] Exp[a s] / ( 2 a ) -
- (I Pi + ExpIntegralEi[a s] Exp[- a s] ) / ( 2 a );
- Transform[trans, 0, Infinity] ] /;
- FreeQ[{a,b}, t] && Negative[b], (* [O & B, Formula 2.21] *)
-
- mylaplace[ (a_. t_ + b_.) CStep[t_] / (t_^2 + d_), t_, s_,
- st_, tlist_, slist_, options_ ] :>
- Block [ {c, trans},
- c = Sqrt[d];
- trans = - CosIntegral[c s] (a Cos[c s] - b Sin[c s] / c) -
- SinIntegral[c s] (a Sin[c s] + b Cos[c s] / c);
- Transform[trans, 0, Infinity] ] /;
- FreeQ[{a,b,c,d}, t] && Positive[d], (* [O & B, Formula 2.19] *)
-
- mylaplace[ (a_. t_ + b_.) CStep[t_] / (t_^2 + d_), t_, s_,
- st_, tlist_, slist_, options_ ] :>
- Block [ {c, trans},
- c = Sqrt[- d];
- trans = - ExpIntegralEi[- c s] Exp[c s] (a - b/c) / (2 f) -
- ExpIntegralEi[c s] Exp[- c s] (a + b/c) / (2 f );
- Transform[trans, 0, Infinity] ] /;
- FreeQ[{a,b,d}, t] && Negative[d], (* [O & B, Formula 2.23] *)
-
- mylaplace[ CStep[t_] / t_, t_, s_, st_, tlist_, slist_, options_ ] :>
- Transform[ - Log[s], 0, Infinity ], (* [Churchill, 324] *)
-
- mylaplace[ (t_ + b_.)^k_. CStep[t_ + b_.], t_, s_,
- st_, tlist_, slist_, options_ ] :>
- Block [ {},
- Assuming[ Positive[k + 1], options];
- Transform[ Exp[b s] Gamma[k+1] / s^(k+1), 0, Infinity ] ] /;
- FreeQ[b, t] && Implies[NumberQ[N[k]], N[k > -1]],
- (* [O & B, Formula 3.3] *)
-
-
- (* B. "Time" functions whose denominators contains powers of t *)
-
- mylaplace[ CPulse[l_, t_ + k_.] / Sqrt[ t_ ( t_ + l_ ) ],
- t_, s_, st_, tlist_, slist_, options_ ] :>
- Transform[ -I Pi Exp[s k] Exp[l s / 2] BesselI[0, l s / 2],
- -Infinity, Infinity ] /;
- FreeQ[{k,l}, t], (* [Churchill, 323 & 331] *)
-
- mylaplace[ t_ CPulse[l_, t_ + k_.] / Sqrt[ t_ ( t_ + l_ ) ], t_, s_,
- st_, tlist_, slist_, options_ ] :>
- Transform[ I Pi l Exp[s k] Exp[l s / 2] BesselI[0, l s / 2] -
- I Pi l Exp[l s / 2] BesselI[1, l s / 2],
- -Infinity, Infinity ] /;
- FreeQ[{k,l}, t], (* [Churchill, 323 & 331] *)
-
-
- (* C. Gaussian function *)
- mylaplace[ Exp[a_. t_^2] CStep[t_], t_, s_, st_, tlist_, slist_, options_ ] :>
- Transform[ Sqrt[Pi / -a] Exp[- s^2 / (4 a)] *
- ( 1 - Erf[s / (2 Sqrt[-a])] ), -Infinity, Infinity ] /;
- FreeQ[a, t], (* [O & B, Formula 5.41] *)
-
-
- (* D. Common waves *)
-
- (* 1. square waves *)
- mylaplace[ SquareWave[c_, t_] CStep[t_], t_, s_,
- st_, tlist_, slist_, options_ ] :>
- Transform[Tanh[c s / 2] / s, 0, Infinity] /;
- FreeQ[c, t], (* [Churchill, 54] *)
-
- (* 2. full-wave rectified sinusoids *)
- mylaplace[ Abs[Sin[a_. t_]] CStep[t_], t_, s_,
- st_, tlist_, slist_, options_ ] :>
- Transform[a Coth[Pi s / (2 a)] / (s^2 + a^2), Abs[Im[a]], Infinity] /;
- FreeQ[a, t], (* [O & B, Formula 7.3] *)
-
- mylaplace[ Abs[Cos[a_. t_]] CStep[t_], t_, s_,
- st_, tlist_, slist_, options_ ] :>
- Transform[ ( s + a Csch[Pi s / (2 a)] ) / (s^2 + a^2),
- Abs[Im[a]], Infinity ] /;
- FreeQ[a, t], (* [O & B, Formula 7.4] *)
-
-
- (* E. Bessel functions *)
-
- (* Bessel functions [Churchill, 327] and [O & B, Formulas 14.1/15.1] *)
- (* Note that formula 14.1 in O & B has a typo in it: -v should be v *)
-
- mylaplace[ BesselI[v_, a_. t_] CStep[t_], t_, s_,
- st_, tlist_, slist_, options_ ] :>
- Block [ {},
- Assuming[ Positive[Re[v] + 1], options ];
- Transform[ (s - Sqrt[s^2 - a^2])^v / (a^v Sqrt[s^2 - a^2]),
- Abs[Re[a]], Infinity ] ] /;
- FreeQ[{a,v}, t] && Implies[NumberQ[N[v]], N[Re[v] > -1]],
-
- mylaplace[ BesselJ[v_, a_. t_] CStep[t_], t_, s_,
- st_, tlist_, slist_, options_ ] :>
- Block [ {},
- Assuming[ Positive[Re[v] + 1], options];
- Transform[ (Sqrt[s^2 + a^2] - s)^v / (a^v Sqrt[s^2 + a^2]),
- Abs[Im[a]], Infinity ] ] /;
- FreeQ[{a,v}, t] && Implies[NumberQ[N[v]], N[Re[v] > -1]],
-
- mylaplace[ BesselJ[v_, a_. t_] CStep[t_] / t_, t_, s_,
- st_, tlist_, slist_, options_ ] :>
- Block [ {},
- Assuming[ Positive[Re[v]], options ];
- Transform[ ( Sqrt[s^2 + a^2] - s )^v / ( v a^v ),
- Abs[Im[a]], Infinity ] ] /;
- FreeQ[{a,v}, t] && Implies[NumberQ[N[v]], Re[N[v]] > 0],
-
- mylaplace[ BesselK[0, j_. Sqrt[t_]] CStep[t_] / Sqrt[t_], t_, s_,
- st_, tlist_, slist_, options_ ] :>
- Transform[ Sqrt[Pi] Exp[j^2 / (8 s)] BesselK[0, j^2 / (8 s)] /
- (2 Sqrt[s]), 0, Infinity ] /;
- FreeQ[j, t],
-
-
- (* F. Exponential forms *)
-
- (* 1. exponential integral [Churchill, 329] *)
- mylaplace[ ExpIntegralEi[a_. t_] CStep[t_], t_, s_,
- st_, tlist_, slist_, options_ ] :>
- Block [ {},
- Assuming[ Negative[a], options ];
- Transform[ - Log[ 1 - s / a ] / s, 0, Infinity ] ] /;
- FreeQ[a, t] && Implies[NumberQ[N[a]], N[a < 0]],
- (* [Churchill, 329] *)
-
- (* 2. error functions, erf *)
- mylaplace[ Erf[a_. Sqrt[t_]] CStep[t_], t_, s_,
- st_, tlist_, slist_, options_ ] :>
- Transform[ a / ( s Sqrt[s + a^2] ), 0, Infinity ] /;
- FreeQ[a, t], (* Modified [Churchill, 326] *)
-
- mylaplace[ Erf[a_. t_ + b_.] CStep[t_], t_, s_,
- st_, tlist_, slist_, options_ ] :>
- Transform[ ( Exp[s^2 / (4 a^2) + s b / a] ( 1 - Erf[b + s / (2 a)] ) +
- Erf[b] ) / s, 0, Infinity ] /;
- FreeQ[{a,b}, t], (* [O & B, Formula 17.59] *)
-
- mylaplace[ Exp[a_/t_] CStep[t_], t_, s_,
- st_, tlist_, slist_, options_ ] :>
- Transform[ -2 I Sqrt[a] BesselK[-1, -2 I Sqrt[a] Sqrt[s]] / Sqrt[s],
- 0, Infinity ] /;
- FreeQ[a, t], (* from Mathematica's Integrate command *)
-
- mylaplace[ Exp[a_/t_] CStep[t_] / Sqrt[t_], t_, s_,
- st_, tlist_, slist_, options_ ] :>
- Transform[ Exp[2 I Sqrt[a] Sqrt[s]] Sqrt[Pi] / Sqrt[s], 0, Infinity ] /;
- FreeQ[a, t], (* from Mathematica's Integrate command *)
-
-
- (* G. Trigonometric functions *)
-
- (* 1. sinc-like forms *)
- mylaplace[ Sin[a_. t_] CStep[t_] / t_, t_, s_,
- st_, tlist_, slist_, options_ ] :>
- Transform[ ArcTan[ a / s ], Abs[Im[a]], Infinity ] /;
- FreeQ[a, t], (* [O & B, Formula 7.5] *)
-
- mylaplace[ Sin[k_. Sqrt[t_]] CStep[t_] / t_, t_, s_,
- st_, tlist_, slist_, options_ ] :>
- Transform[ Pi Erf[ k / ( 2 Sqrt[s] ) ], -Infinity, Infinity ] /;
- FreeQ[k, t], (* [Churchill, 330] *)
-
- (* 2. sine integral Si *)
- mylaplace[ SinIntegral[a_. t_ + b_.] CStep[t_], t_, s_,
- st_, tlist_, slist_, options_ ] :>
- Transform[ Exp[b s / a] ArcTan[a / s] / s, 0, Infinity ] /;
- FreeQ[{a,b}, t], (* [Churchill, 330] *)
-
- (* 3. cosine integral Ci *)
- mylaplace[ CosIntegral[a_. t_] CStep[t_], t_, s_,
- st_, tlist_, slist_, options_ ] :>
- Transform[ ( 2 Log[a] - Log[s^2 + a^2] ) / ( 2 s ), 0, Infinity ] /;
- Positive[a], (* [Churchill, 330] *)
-
- mylaplace[ CosIntegral[a_. t_] CStep[t_], t_, s_,
- st_, tlist_, slist_, options_ ] :>
- Transform[ - Log[1 + s^2/a^2] / (2 s), 0, Infinity ] /;
- FreeQ[a, t], (* [Churchill, 330] *)
-
- (* 4. inverse trigonometric functions *)
- mylaplace[ ArcTan[a_. t_] CStep[t_], t_, s_, st_, tlist_, slist_, options_ ] :>
- Transform[ (CosIntegral[s/a] Sin[s/a] - SinIntegral[s/a] Cos[s/a]) / s,
- 0, Infinity ] /;
- FreeQ[a, t], (* [O & B, Formula 8.4] *)
-
- mylaplace[ ArcCot[a_. t_] CStep[t_], t_, s_, st_, tlist_, slist_, options_ ] :>
- Transform[ ( Pi/2 - CosIntegral[s/a] Sin[s/a] -
- SinIntegral[s/a] Cos[s/a] ) / s, 0, Infinity ] /;
- FreeQ[a, t], (* [O & B, Formula 8.5] *)
-
-
- (* H. Logarithmic forms *)
-
- mylaplace[ Log[a_. t_] CStep[t_], t_, s_, st_, tlist_, slist_, options_ ] :>
- Transform[ - a ( EulerGamma + Log[s / a] ) / s, 0, Infinity ] /;
- FreeQ[a, t], (* Modified [O & B, Formula 6.1] *)
-
- mylaplace[ Log[a_. t_]^2 CStep[t_], t_, s_, st_, tlist_, slist_, options_ ] :>
- Transform[ a ( Pi^2 / 6 + ( EulerGamma + Log[s / a] )^2 ) / s,
- 0, Infinity ] /;
- FreeQ[a, t], (* [O & B, Formula 6.2] *)
-
- mylaplace[ Log[a_ + b_. t_] CStep[t_], t_, s_,
- st_, tlist_, slist_, options_ ] :>
- Block [ {},
- Assuming[ Negative[ Abs[Arg[b/a]] - Pi ], options ];
- Transform[ (Log[a] - Exp[a s / b] ExpIntegralEi[- a s / b]) / s,
- 0, Infinity ] ] /;
- FreeQ[{a,b},t] && Implies[NumberQ[N[a]] && NumberQ[N[b]], N[Abs[Arg[b/a]] < Pi]], (* [O & B, Formula 6.7] *)
-
- mylaplace[ Log[t_^2 + b_] CStep[t_], t_, s_, st_, tlist_, slist_, options_ ] :>
- Block [ {a, trans},
- Assuming[ Positive[b], options];
- a = Sqrt[b];
- trans = 2 ( Log[a] - CosIntegral[a s] Cos[a s] -
- SinIntegral[a s] Sin[a s] ) / s;
- Transform[trans, 0, Infinity] ] /;
- FreeQ[b, t] && Implies[ NumberQ[N[b]], Positive[b] ],
- (* [O & B, Formula 6.11] *)
-
- mylaplace[ Log[1 + b_. t_^2] CStep[t_] / t_, t_, s_,
- st_, tlist_, slist_, options_ ] :>
- Block [ {a, trans},
- a = Sqrt[b];
- trans = CosIntegral[s/a]^2 + SinIntegral[s/a]^2;
- Transform[trans, 0, Infinity] ] /;
- FreeQ[b, t], (* [O & B, Formula 6.15] *)
-
-
-
-
-
- (* IV. T R A N S F O R M P R O P E R T I E S *)
-
-
- (* A. pick off constants *)
- mylaplace[ c_ x_, t_, s_, st_, tlist_, slist_, options_ ] :>
- scaleL[mylaplace[x, t, s, st, tlist, slist, options], c] /;
- FreeQ[c, t] && ! FreeQ[x, t],
-
-
- (* B. additivity -- resulting ROC is intersection of two ROC's *)
- mylaplace[ (x_ + y_) CStep[t_], t_, s_, st_, tlist_, slist_, options_ ] :>
- addL[mylaplace[x CStep[t], t, s, st, tlist, slist, options],
- mylaplace[y CStep[t], t, s, st, tlist, slist, options]],
-
- mylaplace[ x_ + y_, t_, s_, st_, tlist_, slist_, options_ ] :>
- addL[mylaplace[x, t, s, st, tlist, slist, options],
- mylaplace[y, t, s, st, tlist, slist, options]],
-
- mylaplace[ (x_ + y_) CStep[t_] / c_, t_, s_, st_, tlist_, slist_, options_ ] :>
- addL[mylaplace[x CStep[t] / c, t, s, st, tlist, slist, options],
- mylaplace[y CStep[t] / c, t, s, st, tlist, slist, options]],
-
- mylaplace[ (x_ + y_) / c_, t_, s_, st_, tlist_, slist_, options_ ] :>
- addL[mylaplace[x / c, t, s, st, tlist, slist, options],
- mylaplace[y / c, t, s, st, tlist, slist, options]],
-
-
- (* C. Time reversal *)
- mylaplace[ x_. CStep[-t_], t_, s_, st_, tlist_, slist_, options_ ] :>
- antiCausalL [ mylaplace [ (x /. t -> - t) CStep[t], t, s,
- st, tlist, slist, options ],
- s ],
-
-
- (* D. Shift and delays -- every continuous function should *)
- (* be a function times either a CStep or an Delta, and *)
- (* the rule base already handles the Delta case. *)
- mylaplace[ f_. CStep[a_ t_ + b_.], t_, s_, st_, tlist_, slist_, options_ ] :>
- mylaplace[ f CStep[t + b/a] CStep[a] + f CStep[-t - b/a] CStep[-a],
- t, s, st, tlist, slist, options ] /;
- FreeQ[{a, b}, t], (* [Bracewell, 67] *)
-
- mylaplace[ f_. CStep[t_ + m_], t_, s_, st_, tlist_, slist_, options_ ] :>
- scaleL [ mylaplace [ (f /. t -> t - m) CStep[t], t, s,
- st, tlist, slist, options ],
- Exp[m s] ] /;
- FreeQ[m, t],
-
- mylaplace[ f_. CStep[m_ - t_], t_, s_, st_, tlist_, slist_, options_ ] :>
- scaleL [ mylaplace [ (f /. t -> t + m) CStep[-t], t, s,
- st, tlist, slist, options ],
- Exp[- m s] ] /;
- FreeQ[m, t],
-
- mylaplace[ f_[t_ + b_], t_, s_, st_, tlist_, slist_, options_ ] :>
- scaleL[ mylaplace[ f[t], t, s, st, tlist, slist, options],
- Exp[b s] ] /;
- FreeQ[b, t],
-
- (*
- mylaplace[ f_[t_ + b_] CStep[t_], t_, s_, st_, tlist_, slist_, options_ ] :>
- scaleL[ mylaplace[ f[t] CStep[t], t, s, st, tlist, slist, options],
- Exp[b s] ] /;
- FreeQ[b, t],
- *)
-
-
- (* E. Multiplication by c^(at+b) -- covers exponential case, *)
- (* b can be a function of t *)
- mylaplace[ c_^(b_. + a_. t_) x_., t_, s_, st_, tlist_, slist_, options_ ] :>
- lMultiplyByExp [ mylaplace[c^b x, t, s, st, tlist, slist, options],
- s, -a Log[c] ] /;
- FreeQ[{a,c}, t], (* Modified [Franklin, 590] *)
-
-
- (* F. Multiplication by t^m [Franklin, 590] *)
- mylaplace[ t_^m_. x_., t_, s_, st_, tlist_, slist_, options_ ] :>
- lDerivative[ mylaplace[x, t, s, st, tlist, slist, options], s, m ] /;
- IntegerQ[m] && m > 0,
-
-
- (* G. Modulation *)
-
- (* 1. multiplication by a cosine function [Bracewell, 224] *)
- mylaplace[ Cos[b_ + w_. t_] f_, t_, s_, st_, tlist_, slist_, options_ ] :>
- mylaplace [ Cos[b] Cos[w t] f - Sin[b] Sin[w t] f, t, s,
- st, tlist, slist, options ],
- mylaplace[ Cos[w_. t_] f_. CStep[t_], t_, s_, st_, tlist_, slist_, options_ ] :>
- Block [ {trans},
- trans = mylaplace[f CStep[t], t, s, st, tlist, slist, options];
- scaleL[addL[substituteForL[trans, s, s + I w],
- substituteForL[trans, s, s - I w] ],
- 1/2] ] /;
- FreeQ[w, t],
-
- (* 2. multiplication by a sine function [Bracewell, 224] *)
- mylaplace[ Sin[b_ + w_. t_] f_, t_, s_, st_, tlist_, slist_, options_ ] :>
- mylaplace [ Sin[b] Cos[w t] f + Cos[b] Sin[w t] f, t,
- s, st, tlist, slist, options ],
- mylaplace[ Sin[w_. t_] f_. CStep[t_], t_, s_, st_, tlist_, slist_, options_ ] :>
- Block [ {trans},
- trans = mylaplace[f CStep[t], t, s, st, tlist, slist, options];
- scaleL[subL[substituteForL[trans, s, s + I w],
- substituteForL[trans, s, s - I w] ],
- I/2] ] /;
- FreeQ[w, t],
-
-
- (* H. Derivative *)
- mylaplace[ Derivative[m_][f_][t_],
- t_, s_, st_, tlist_, slist_, options_ ] :>
- Block [ {dialogue},
- dialogue = SameQ[ Replace[Dialogue, options], All ];
- Assuming[ m > 0, dialogue ];
- If [ dialogue && ! IntegerQ[m],
- Print[ "and that ", m, " is an integer" ] ];
- scaleL[ mylaplace[f[t], t, s, st, tlist, slist, options],
- s^m ] ] /;
- Implies[NumberQ[m], IntegerQ[m] && m > 0], (* [Bracewell, 224] *)
-
- mylaplace[ Derivative[m_][f_][t_] CStep[t_],
- t_, s_, st_, tlist_, slist_, options_ ] :>
- Block [ {dialogue},
- dialogue = SameQ[ Replace[Dialogue, options], All ];
- Assuming[ m > 0, dialogue ];
- If [ dialogue && ! IntegerQ[m],
- Print[ "and that ", m, " is an integer" ] ];
- timeDerivative[mylaplace[f[t], t, s, st, tlist, slist, options],
- s, m, f[t], t] ] /;
- Implies[NumberQ[m], IntegerQ[m] && m > 0], (* [Bracewell, 224] *)
-
-
- (* I. Integral with time as upper limit *)
- mylaplace[ Integrate[f_, terms1___, {a_, 0, t_}, terms2___],
- t_, s_, st_, tlist_, slist_, options_ ] :>
- Block [ {leftover, trans},
- leftover = ToCollection[ terms1, terms2 ];
- trans = mylaplace[f /. a -> t, t, s, st, tlist, slist, options];
- If [ SameQ[{leftover}, {}],
- scaleL [ trans, 1/s ],
- scaleL [ trans, 1/s Integrate[f, leftover] ] ] ],
- (* [Churchill, 323] *)
-
- mylaplace[ Integrate[f_, terms1___, t_, terms2___],
- t_, s_, st_, tlist_, slist_, options_ ] :>
- Block [ {leftover, trans},
- leftover = ToCollection[ terms1, terms2 ];
- trans = mylaplace[f, t, s, st, tlist, slist, options];
- If [ SameQ[{leftover}, {}],
- scaleL [ trans, 1/s ],
- scaleL [ trans, 1/s Integrate[f, leftover] ] ] ],
- (* [Churchill, 323] *)
-
-
- (* J. Divide by powers of t *)
- mylaplace[ f_. t_^m_, t_, s_, st_, tlist_, slist_, options_ ] :>
- integrateL[mylaplace[f t^(m+1), t, s, st, tlist, slist, options], s] /;
- IntegerQ[m] && m < 0, (* [Nilsson, 516] *)
-
-
- (* K. Conjugation: L{ Conj f[-t] } --> Conj F(s) *)
- mylaplace[ Conjugate[x_], t_, s_, st_, tlist_, slist_, options_ ] :>
- conjL[mylaplace[x /. t -> -t, t, s, st, tlist, slist, options], s],
- (* [Bracewell, 122] *)
-
-
- (* L. Convert forms with Abs[a t] into two-sided transforms *)
- mylaplace[ f_, t_, s_, st_, tlist_, slist_, options_ ] :>
- mylaplace[ absDialogue[f, t, options],
- t, s, st, tlist, slist, options ] /;
- ! FreeQ[ f, Abs[c_. t] ],
-
-
-
-
- (* V. S T R U C T U R E S *)
-
-
- (* A. Convolution *)
- mylaplace[ CConvolve[t_][x1_, x2_, rest__], t_, s_,
- st_, tlist_, slist_, op_ ] :>
- multL[mylaplace[x1, t, s, st, tlist, slist, op],
- mylaplace[CConvolve[t][x2, rest], t, s,
- st, tlist, slist, op]],
-
- mylaplace[ CConvolve[t_][x1_, x2_], t_, s_, st_, tlist_, slist_, op_ ] :>
- multL[mylaplace[x1, t, s, st, tlist, slist, op],
- mylaplace[x2, t, s, st, tlist, slist, op]],
-
- mylaplace[ CConvolve[tconv_][x1_, x2_], t_, s_, st_, tlist_, slist_, op_ ] :>
- convolveL[ CConvolve[Complement[tconv, {t}]],
- mylaplace[x1, t, s, st, tlist, slist, op],
- mylaplace[x2, t, s, st, tlist, slist, op]] /;
- ListQ[tconv] && MemberQ[tconv, t],
-
-
- (* B. Continuous FIR filters. *)
- mylaplace[ CFIR[t_, h_List, Roots -> r_], t_, s_,
- st_, tlist_, slist_, options_ ] :>
- Block [ {i, numzeroes},
- If [ Length[h] != Length[r] + 1,
- Message[ CFIR::invalid ] ];
- numzeroes = Length[r];
- Transform[ Product[(s - r[[i]]), {i, 1, numzeroes}],
- -Infinity, Infinity ] ] /;
- Length[Dimensions[h]] == 1,
-
- mylaplace[ CFIR[t_, h_, rest___], t_, s_, st_, tlist_, slist_, options_ ] :>
- Transform[ h . Table[s^k, {k, 0, Length[h] - 1}], -Infinity, Infinity ],
-
- mylaplace[ CFIR[all__] [ x__ ], t_, s_, st_, tlist_, slist_, options_ ] :>
- multL[mylaplace[CFIR[all], t, s, st, tlist, slist, options],
- mylaplace[x, t, s, st, tlist, slist, options]],
-
-
- (* C. One-dimensional analog IIR filters. *)
- (* Region of convergence is incorrect *)
- mylaplace[ CIIR[t_, a_List, Roots -> r_], t_, s_,
- st_, tlist_, slist_, options_ ] :>
- Block [ {i, numpoles},
- If [ Length[a] != Length[r] + 1,
- Message[ CIIR::invalid ] ];
- numpoles = Length[r];
- rminus = Max[Re[r]];
- If [ ListQ[rminus], rminus = N[rminus] ];
- Transform[ 1 / Product[(s - r[[i]]), {i, 1, numpoles}],
- rminus, Infinity ] ] /;
- Length[Dimensions[a]] == 1,
-
- mylaplace[ CIIR[t_, a_List], t_, s_, st_, tlist_, slist_, options_ ] :>
- Block [ {alist, denom, index, rminus, len},
- alist = ToList[a];
- len = Length[alist];
- denom = a[[1]] +
- Sum[ alist[[index]] s^(index - 1), {index, 2, len} ];
- rminus = Max[ Re[ GetRootList[denom, s] ] ];
- Transform[ 1 / denom, rminus, Infinity ] ] /;
- Length[Dimensions[a]] == 1,
-
- mylaplace[ CIIR[all__] [x__], t_, s_, st_, tlist_, slist_, options_ ] :>
- multL[mylaplace[CIIR[all], t, s, st, tlist, slist, options],
- mylaplace[x, t, s, st, tlist, slist, options]],
-
-
- (* D. Imaginary part of a sequence *)
- mylaplace[ Im[x_], t_, s_, st_, tlist_, slist_, options_ ] :>
- Block [ {trans},
- trans = mylaplace[x, t, s, st, tlist, slist, options];
- scaleL[ subL [ trans,
- conjL[substituteForL[trans, s, -s], s] ],
- 1/2 ] ],
-
-
- (* E. Periodic sequence with period k *)
- mylaplace[ Periodic[a_, t_][f_] CStep[t_], t_, s_,
- st_, tlist_, slist_, options_ ] :>
- scaleL[mylaplace[f CPulse[a, t], t, s, st, tlist, slist, options],
- 1 / ( 1 - Exp[- a s] ) ] /;
- FreeQ[a, t],
-
-
- (* F. Real part of a function *)
- mylaplace[ Re[x_], t_, s_, st_, tlist_, slist_, options_ ] :>
- Block [ {trans},
- trans = mylaplace[x, t, s, st, tlist, slist, options];
- scaleL [ addL [ trans,
- conjL[substituteForL[trans, s, -s], s] ],
- 1/2] ],
-
-
- (* G. Reverse operator *)
- mylaplace[ Rev[t_][x_], t_, s_, st_, tlist_, slist_, options_ ] :>
- antiCausalL[ mylaplace[ x, t, s, st, tlist, slist, options ], s ],
-
-
- (* H. Shift operator *)
- mylaplace[ Shift[m_, t_][x_], t_, s_, st_, tlist_, slist_, options_ ] :>
- scaleL[mylaplace[x, t, s, st, tlist, slist, options], Exp[- m s]] /;
- FreeQ[m, t],
-
-
- (* I. Summation operator *)
- mylaplace[ a_. Summation[i_, ib_, ie_, inc_][x_], t_, s_,
- st_, tlist_, slist_, options_ ] :>
- summationL[ mylaplace[a x, t, s, st, tlist, slist, options],
- Summation[i, ib, ie, inc] ],
-
-
-
- (* VI. S T R A T E G I E S *)
-
-
- (* A. Similarity -- f(at) <--> F(s/a) / |a| [Bracewell, 224] *)
- (* only perform this if a is neither 1 nor 0 *)
- (* must be done after operator rules because the *)
- (* substitution t -> t/scale messes up operators *)
- mylaplace[ f_ CStep[t_], t_, s_, st_, tlist_, slist_, options_ ] :>
- Block [ {newf, scale},
- scale = ScalingFactor[f, t];
- newf = ( f /. t -> t/scale ) CStep[t];
- similarityL[ mylaplace[newf, t, s, st, tlist, slist, options],
- s,
- scale ] ] /;
- similarityQ[f, t],
-
- mylaplace[ f_, t_, s_, st_, tlist_, slist_, options_ ] :>
- Block [ {newf, scale},
- scale = ScalingFactor[f, t];
- newf = ( f /. t -> t/scale );
- similarityL[ mylaplace[newf, t, s, st, tlist, slist, options],
- s,
- scale ] ] /;
- similarityQ[f, t],
-
-
- (* B. Place sub-expressions over a common denominator *)
- mylaplace[ f_. a_^(v_. t_ + k_.) / b_^(u_. t_ + l_.), t_, s_,
- st_, tlist_, slist_, options_ ] :>
- mylaplace[ (a^v/b^u)^t f a^k/b^l, t, s, st, tlist, slist, options ],
-
-
- (* C. Expand out products like (t + 1) (t + 2) ... *)
- mylaplace[ x_, t_, s_, st_, tlist_, slist_, options_ ] :>
- mylaplace[ Distribute[x], t, s, st, tlist, slist, options ] /;
- SameQ[Head[x], Times] && ! SameQ[Distribute[x], x],
-
-
- (* D. Expands out all numerator in the expression *)
- mylaplace[ x_, t_, s_, st_, tlist_, slist_, options_ ] :>
- mylaplace [ Expand[x], t, s,
- SetStateField[st, expandfield, False],
- tlist, slist, options ] /;
- GetStateField[st, expandfield] && ! SameQ[x, Expand[x]],
-
-
- (* E. Expands out all numerators and denominators in expression *)
- mylaplace[ x_, t_, s_, st_, tlist_, slist_, options_ ] :>
- mylaplace[ ExpandAll[x], t, s,
- SetStateField[st, expandallfield, False],
- tlist, slist, options ] /;
- GetStateField[st, expandallfield] && ! SameQ[x, ExpandAll[x]],
-
-
- (* F. Collect all terms in expression *)
- mylaplace[ x_, t_, s_, st_, tlist_, slist_, options_ ] :>
- mylaplace[ MyCollectAll[x, t], t, s,
- SetStateField[st, collectallfield, False],
- tlist, slist, options ] /;
- GetStateField[st, collectallfield],
-
-
- (* G. Reduces all signal processing operations to their *)
- (* mathematical forms *)
- mylaplace[ x_, t_, s_, st_, tlist_, slist_, options_ ] :>
- Block [ {newx},
- newx = ToContinuous[ TheFunction[x] ];
- state = If [ SameQ[newx, x], st, initLstate[] ];
- state = SetStateField[state, thefunfield, False];
-
- mylaplace[ newx, t, s, state, tlist, slist, options ] ] /;
- GetStateField[st, thefunfield],
-
-
- (* H. Apply definition if flag is set *)
- mylaplace[ x_, t_, s_, st_, tlist_, slist_, options_ ] :>
- Block [ {state, trans},
- state = SetStateField[st, definitionfield, False];
- trans = Integrate[x Exp[- s t], {t, -Infinity, Infinity}];
- If [ SameQ[Head[trans], Integrate],
- mylaplace[x, t, s, state, tlist, slist, options],
- definitionDialogue[ x CStep[t],
- Transform[ trans, 0, Infinity ],
- Integrate, options ] ] ] /;
- GetStateField[st, definitionfield] && Replace[Definition, options],
-
-
- (* I. Two-sided transform if all else fails *)
- mylaplace[ x_, t_, s_, st_, tlist_, slist_, options_ ] :>
- Block [ {trans},
- trans = MyLaPlace[ x CStep[t] + x CStep[-t], t, s,
- nullLstate[], tlist, slist, options ];
- If [ TrueQ[LForm[trans] && TheFunction[trans] != 0],
- MyMessage[Transform::twosided, trans, x],
- mylaplace[x, t, s, state, tlist, slist, options] ] ] /;
- GetStateField[st, stepfield]
-
- }
-
-
- (* E N D P A C K A G E *)
-
- End[]
- EndPackage[]
-
- If [ TrueQ[ $VersionNumber >= 2.0 ],
- On[ General::spell ];
- On[ General::spell1 ] ];
-
-
- (* A L I A S E S *)
-
- Unprotect[ LaPlaceTransform ]
- LaPlaceTransform = LaPlace
- LaPlaceTransform::usage = LaPlace::usage
- Protect[ LaPlaceTransform ]
-
-
- (* H E L P I N F O R M A T I O N *)
-
- Combine[ SPfunctions, { LaPlace } ]
- Protect[ LaPlace ]
-
-
- (* E N D M E S S A G E *)
-
- Print["The forward Laplace transform rule base LaPlace has been loaded."]
- Null
-